function mod(a,n){
    return ((a%n)+n)%n;
}
function scale(x, totalwidth){
    return (1 - ((1/totalwidth)*x)**2);
}

function SlideItem(template,startOffset,index, lowerBound,higherBound,center, width, childWidth){
    this.template = template;
   //this.template.append("<div class='debug'></div>")
    this.slideOffset = startOffset;
    this.index = index;
    this.lowerBound = lowerBound;
    this.higherBound = higherBound;
    this.center = center;
    this.width = width;
    this.childWidth = childWidth;
}
SlideItem.prototype = {
    constructor: SlideItem,
    getIndex:function(){
        return this.index;
    },
    check:function(index){
        if(this.slideOffset<this.lowerBound||this.slideOffset>this.higherBound||this.index<index-1||this.index>index+5){
            this.template.remove();
            return false;
        }
        return true;
    },
    moveTo:function(baseIndex,delta, offset, animate = false){
        this.template.find(".debug").html( (this.index-baseIndex)+" "+(offset));
        this.slideOffset= ((this.index-baseIndex)*delta-offset);
        x= (this.slideOffset - this.center);
        spaceCorr = (this.childWidth*0.9*(1-(0.69*scale(x,this.width/2)+0.31)))*(x<0?1:-1); //Quadratic Function to Compensate size
        if(animate){
            this.template.css("transition","transform 300ms ease");
        }else{
            this.template.css("transition","");
        }
        this.template.css("z-index",Math.round(scale(x,this.width/2)*15));
        this.template.css("transform","translateX("+(this.slideOffset+spaceCorr )+"px) scale("+(0.69*scale(x,this.width/2)+0.31)+")");
    }

}
function Slider(root){
    this.root = $(root);
    this.root.find(".next").click(this.next.bind(this));
    this.root.find(".prev").click(this.prev.bind(this));
    this.items = [];
    this.childWidth = 0;
    this.scrollOffset = 0;

    this.loadedList = [];
    this.highestIndex = 0;
    this.lowestIndex = 0;
    inner_wrapper = this.root.find(".slider-inner-wrapper");
    inner_wrapper.children().each(function(i,o){o= $(o); o.margi = parseInt(o.css('marginLeft'))+parseInt(o.css('marginRight'));this.items.push(o)}.bind(this));

    this.init();

    tx = 0;
    xstart = 0;
    ty = 0;
    touch = false;
    isTouch = false;
    this.root.on("touchstart",(e)=>{
        touch=true;
        isTouch=true;
        xstart = tx = e.targetTouches[0].screenX;
        ty = e.targetTouches[0].screenY;
    });
    this.root.on("touchend",function(e){
            touch=false;
            this.move(1,true);
        }.bind(this));

    this.root.on("touchmove",(function(e){
        this.move((e.targetTouches[0].screenX-tx)*1.3);

        if(Math.abs(xstart-e.targetTouches[0].screenX)>20||Math.abs(e.targetTouches[0].screenX-tx)*3>Math.abs(e.targetTouches[0].screenY-ty)){
            e.preventDefault();
            e.stopPropagation();
            e.stopImmediatePropagation();
        }
        tx = e.targetTouches[0].screenX;
        ty = e.targetTouches[0].screenY;
    }.bind(this)));



    $(window).resize(function(){
        if(this.SliderWidth != this.root.innerWidth()){
            this.scrollOffset=Math.round(this.scrollOffset* this.root.innerWidth()/this.SliderWidth);
            this.init();

            this.move(0,true);
        }
    }.bind(this));
    this.move(0);
}

Slider.prototype = {
    constructor: Slider,
    init: function(){
        this.loadedList = [];
        inner_wrapper = this.root.find(".slider-inner-wrapper");
        this.SliderWidth = this.root.innerWidth();
        this.childWidth = Math.round(this.SliderWidth/5);
        this.SliderWidth = this.root.innerWidth();
        for (item of this.items){
            const cw = this.childWidth;
            item.width(cw * 0.90);
        }
        inner_wrapper.html("");


    },
    next:function(){
        this.move(this.childWidth,true);
    },
    prev:function(){
        this.move(-this.childWidth,true);
    },
    move:function(delta,correction=false){
        delta = Math.round(delta);
        this.scrollOffset+=delta;
        this.scrollOffset = Math.round(this.scrollOffset);
        if(correction){

            errorOffset = Math.round(mod(this.scrollOffset,this.childWidth));
            if(this.childWidth/2 < errorOffset){
                this.scrollOffset+=this.childWidth-errorOffset
            }else{
                this.scrollOffset-=errorOffset;
            };
        }

        currIndex = Math.floor((-this.scrollOffset/this.childWidth));
        this.highestIndex=-9999999999;
        this.lowestIndex=9999999999;
        this.loadedList = this.loadedList.filter(function(item){
            item.moveTo(currIndex,this.childWidth, mod(-this.scrollOffset,this.childWidth) ,correction);
            if(!item.check(currIndex)){
                return false;
            }else{
                this.highestIndex = Math.max(item.getIndex(),this.highestIndex);
                this.lowestIndex = Math.min(item.getIndex(),this.lowestIndex);
            }
            return true;
        }.bind(this))

        for(var i = -1;i<=5;i++){

            if(currIndex+i > this.highestIndex ||currIndex+i < this.lowestIndex){
                el = this.items[mod(currIndex+i ,this.items.length)].clone();
                this.root.find(".slider-inner-wrapper").append(el);
                newItem = new SlideItem(el,i*this.childWidth, currIndex+i  , -this.childWidth,this.childWidth*6,this.childWidth*2,this.SliderWidth,this.childWidth);
                newItem.moveTo(currIndex,this.childWidth,mod(-this.scrollOffset,this.childWidth));
                if(newItem.check(currIndex)){
                    this.loadedList.push(newItem);
                    this.highestIndex = Math.max(currIndex+i,this.highestIndex);
                    this.lowestIndex = Math.min(currIndex+i,this.lowestIndex);
                }

            }
        }
    }

}

function SmoothAnimation(div,x,y,r){
    this.root = div;
    this.animation = anime({
      targets: div,
      easing: 'linear',
      duration:20,
      translateX: x,
      translateY: y,
      rotate: r,
      autoplay: false
    });
    this.ref = null;

        $(window).scroll(function(){
                if (null ===  this.ref) {
                   this.ref = requestAnimationFrame(this.update.bind(this));
                }
        }.bind(this));
}
SmoothAnimation.prototype = {
    constructor: SmoothAnimation,
    update: function() {
                     var progress = this.animation.progress / 100;
                     var proxyProgress = Math.max(0,Math.min(($(window).scrollTop()-$(this.root).offset().top+700)/1000,1));
                     var diff = proxyProgress - progress;
                     progress += (proxyProgress - progress) * 0.1;
                     this.animation.seek(progress * 20);

                     if (Math.abs(diff) > 0.000005) {
                       this.ref = requestAnimationFrame(this.update.bind(this));
                     } else if (this.ref) {
                       cancelAnimationFrame(this.ref);
                       this.ref = null;
                     }
                 }
    }
$(document).ready(()=>{
    $(".slider-outer-wrapper").each((i,sld)=> new Slider(sld));

   // new SmoothAnimation("#earth",-20,40,1);
    new SmoothAnimation("#sun",-20,40,0);
    new SmoothAnimation("#sonde",40,-90,"-2deg");
})


function Multislider(containername){
  //This slider has no Text for the selected Image
  //its a simple row where the first Image is highlighted
	this.slides = [];
  this.containerName = containername;
  this.parent = $("#"+ containername);
  this.touchsurface = this.parent.find(".touchsurface");
  this.container = this.parent.children(".slidercontainer");
  this.wrapper = this.container.children(".sliderwrapper");
  this.pos = 0;
  this.startY = 0;
  this.deltaPos = 0;
  this.slideOffset = 0;
  this.startX = 0;
  $(document).ready(this.initial.bind(this));
  $(window).resize(function(){
    this.wrapper.addClass("noanimation");
    this.update();
  }.bind(this));
}

Multislider.prototype ={
	constructor: Multislider,
  initial: function(){
		this.parent = $("#"+ this.containerName);
    this.touchsurface = this.parent.find(".touchsurface");
 		this.container = this.parent.children(".slidercontainer");
  	this.wrapper = this.container.children(".sliderwrapper");
    instance = this;
    this.wrapper.find(".slide").each((i,o)=>{

      callback = ()=>{
          this.pos = i;
         // openImage($(o).find("img").attr("src"));
          this.update();
        }
      $(o).click(callback.bind(this));
    	this.slides.push(o);
    });
    this.parent.find(".left").click(this.slideLeft.bind(this));
    this.parent.find(".right").click(this.slideRight.bind(this));

    this.touchsurface.bind("touchstart", (e) => {
        var touch = e.originalEvent.touches[0] || e.originalEvent.changedTouches[0];
        this.startx = parseInt(touch.clientX);
      	this.starty = parseInt(touch.clientY);
    });
    this.touchsurface.bind("touchmove", (e) => {
        var touch = e.originalEvent.touches[0] || e.originalEvent.changedTouches[0];
        var distx = parseInt(touch.clientX) - this.startx;
        var disty = parseInt(touch.clientY) - this.starty;
      	if( (Math.abs(distx)*2>Math.abs(disty) || Math.abs(disty)<6) && e.cancelable){
          e.preventDefault();
        }
        this.slideOffset = distx;
        this.update(false);
    });
    this.touchsurface.bind("touchend", (e) => {
      	  so = -this.slideOffset/this.getSlideWidth();
		  if(so > 0.1 && so < 0.5){
			 this.deltaPos++;
		  }
		  if(so < -0.1 && so > -0.5){
			 this.deltaPos--;
		  }
       	this.slideOffset = 0;
        this.pos += this.deltaPos;
        this.update();

    });

    this.update();
  },
  slideLeft: function(){
  	this.pos--;
    this.update();
  },
  slideRight: function(){
    this.pos++;
    this.update();
  },
  getSlideWidth: function(){
  	return this.wrapper.find(".slide").width();
  },
  getSliderWidth: function(){
  	return this.container.width();
  },
  update:function(animated = true){
  	  sliderWidth = this.getSliderWidth();
      slideWidth = this.getSlideWidth();
  	  maxSlide = this.slides.length - (sliderWidth/slideWidth);
      maxOffset = maxSlide*slideWidth;
      maxOffset+= parseInt($(".selected").css("margin-left"))*4;
      if(this.pos<0) this.pos = 0;
   	  if(this.pos>=this.slides.length) this.pos = this.slides.length-1;
      this.deltaPos=-Math.round(this.slideOffset/slideWidth);
      if(this.pos + this.deltaPos<0) this.deltaPos = -this.pos;
      if(this.pos + this.deltaPos>=this.slides.length) this.deltaPos = this.slides.length-this.pos;
      offset = this.pos*slideWidth - this.slideOffset;
      if(offset<0) offset = 0;
      if(offset>maxOffset) offset = maxOffset;
      this.wrapper.children(".slide").removeClass("selected");
      this.wrapper.children(".slide").css("transform","");
      this.wrapper.children(".slide:nth-child("+(this.pos+this.deltaPos+1)+")").addClass("selected");
      if(!animated){
      	this.wrapper.addClass("noanimation");
      }else{
      	this.wrapper.removeClass("noanimation");
       }
      this.wrapper.css("transform","translateX("+(-offset)+"px)");
  }
};

svg = `<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M18.1568 16.8823L16.9698 18.0562C16.0949 18.9149 14.9598 20.0188 13.5639 21.3684C12.6917 22.2118 11.3079 22.2117 10.4358 21.3682L6.94466 17.9723C6.5059 17.5415 6.13863 17.1782 5.84279 16.8823C2.44238 13.4819 2.44238 7.96878 5.84279 4.56837C9.2432 1.16796 14.7564 1.16796 18.1568 4.56837C21.5572 7.96878 21.5572 13.4819 18.1568 16.8823ZM14.5 11.0001C14.5 9.61924 13.3806 8.49986 11.9998 8.49986C10.619 8.49986 9.49958 9.61924 9.49958 11.0001C9.49958 12.3809 10.619 13.5003 11.9998 13.5003C13.3806 13.5003 14.5 12.3809 14.5 11.0001Z" fill="COLOR"/>
</svg>
`;
function mapView(root){
    this.root = root;

    zoom = parseInt( this.root.data("zoom") ) ;
    zoom= this.root.data("zoom")?this.root.data("zoom"):6;
    this.map = L.map(this.root.find(".ncf-mapcontainer").get(0)).setView({lon: 0, lat: 0}, zoom);
    this.markerList = [];
    this.selected = null;
      // add the OpenStreetMap tiles
      L.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', {
        maxZoom: 19,
        attribution: '&copy; <a href="https://openstreetmap.org/copyright">OpenStreetMap contributors</a>'
      }).addTo(this.map);
      // show the scale bar on the lower left corner
      L.control.scale({imperial: true, metric: true}).addTo(this.map);
    first = true;
    
    this.root.find(".ncf-map-item").each(function(i,o){
        const ident = $(o).find(".identifyer");
        const LeafIcon = L.icon({

                iconUrl: 'data:image/svg+xml;base64,' + btoa(svg.replace("COLOR",ident.data("color")||'#ff0000')),
                iconSize:     [30, 30],
                iconAnchor:   [15, 29],
                tooltipAnchor:  [12, -17],

        });

        const op = $(o);
        const marker = L.marker([ident.data("lat"),ident.data("lon")*1],{icon:LeafIcon});
        marker.setOpacity(0.8);
        marker.bindTooltip(ident.data("popup"))
        marker.addTo(this.map)
        this.markerList[ident.attr('id')]=marker;

        const enter = function(){
            this.hoverStart(op,ident);
        }.bind(this);
        const leave = function(){
            this.hoverEnd(op,ident);
        }.bind(this);
        const click = function(){
            this.clickItem(op,ident);
        }.bind(this);
        marker.on("mouseover",enter);
        marker.on("mouseout",leave);
        marker.on("click",click);
        op.mouseenter(enter);
        op.mouseleave(leave);
        op.on("click",click);
                if(first){
                 first = false;
                 console.log(marker.getLatLng());
                 this.map.setView(marker.getLatLng());
                }
    }.bind(this));

}



mapView.prototype={
    constructor: mapView,
    hoverStart: function(o,ident){
        this.markerList[ident.attr('id')].openTooltip();
        $(o).addClass("hover");
        if(ident.attr('id') == this.selected) return;
        this.markerList[ident.attr('id')].setOpacity(1);

    },
    hoverEnd: function(o,ident){
        this.markerList[ident.attr('id')].closeTooltip();
        $(o).removeClass("hover");
        if(ident.attr('id') == this.selected) return;
        this.markerList[ident.attr('id')].setOpacity(0.8);

    },
    clickItem: function(o,ident){
        if(this.selected != null){
            this.markerList[this.selected].setOpacity(0.8);
            this.root.find(".ncf-map-item").removeClass("selected");
        }
        this.selected = ident.attr('id');
        this.markerList[this.selected].setOpacity(1);
        o.addClass("selected");
        this.map.setView(this.markerList[this.selected].getLatLng());
        console.log("click");
    },
    update: function(){
        templist = []
        for( data in this.markerList){
            templist[data] = this.markerList[data];
        }
        this.root.find(".ncf-map-item").each(function(i,o){
            const ident = $(o).find(".identifyer");
            const op = $(o);
            op.mouseenter(function(){
                this.hoverStart(op,ident);
            }.bind(this));

            op.mouseleave(function(){
                this.hoverEnd(op,ident);
            }.bind(this));

            op.click(function(){
                this.clickItem(op,ident);
            }.bind(this));

            templist[ident.attr('id')].addTo(this.map);
            delete templist[ident.attr('id')];
        }.bind(this));
        for (item in templist){
            templist[item].remove();
        }
    }
}


$(document).ready(()=>{
    $(".ncf-map").not('.ncf-filterlist').each((i,o)=>{
        new mapView($(o));
    });

    $(".ncf-map.ncf-filterlist").each((i,o)=>{
        fl = new FilterList($(o));
        map =new mapView($(o));
        fl.onUpdate = function(){map.update()};
    });
});
